IP Probe: A telnet-like IP probe utility for z/tpf

tpf
tcpip
Author

Ian S. Worthington

Published

August 16, 2023

IP Probe: A “telnet-like” IP probe utility for z/TPF

Background

Whilst the use of telnet as a terminal emulator for remote systems is, baring a small number of niche cases, all but obsolete, it remains useful on many platforms as a quick and easy way to test tcp/ip connectivity to a remote address and port where nmap might be overkill, not installed, or otherwise unavailable. z/tpf does not provide such a facility. IP Probe fulfils this requirement.

Design objectives

Unlike most programs, IP Probe is designed to expose its inner workings specifically to identify any point of failure and the reason for that. Thus, its output is somewhat verbose, for example:

IP Probe Utility Version: 1.0; built: Jun 7 2023 11:15:52
Creating TCP socket…
…Created socket 12582949
Setting receive/connect timeout of 10 seconds on socket 12582949…
…Options set, rc = 0
Connecting socket 12582949 to 10.27.186.207:21…
…Connected TCP socket, rc = 0
Sending on socket 12582949 (15 bytes): EtoA(Metatron speaks)…
…Sent 15 bytes
Receiving on socket 12582949…
…Received 42 bytes: 220 TPF FTP server (Version 1.02) ready.
Setting receive/connect timeout of 1 seconds on socket 12582949…
…Options set, rc = 0
Receiving on socket 12582949…
…Receive timeout: no data received
Closing TCP socket 12582949…
…Closed TCP socket, rc = 0
Test finished.

The sequence of events is:

  1. Create a TCP socket.

  2. Set a primary timeout period to be used for both the initial connection and the receipt of the first response datagram.

  3. Attempt to connect to target, wait for connection to be established.

  4. Send some data.

  5. Attempt to receive a datagram. We’re not overly bothered by its contents. Indeed the data we send is likely to be rejected by most servers so this operation will oftentimes fail.

  6. In case any datagram sent to us has been fragmented, or more than one was sent, we’re going to issue another receive. But we don’t want to wait for a long time so set a short secondary timeout period.

  7. Now issue the secondary receive.

  8. On receiving a timeout or an error from the secondary receive close the socket and terminate the connection.

Usage

The utility itself provides full help text:

> zuipp –help

zuipp [-hV] [–version] [-d <string>] [-1 <positive integer>]
[-2 <positive integer>] IP_Address TCP_Port

Where:

  -d <string>, –data <string>
    The message data to send.

  1 <positive integer>, –timeout1 <positive integer>
    Timeout for connect and first receive.

  -2 <positive integer>, –timeout2 <positive integer>
    Timeout for subsequent receives.

  -V, –verbose (accepted multiple times)
    Show some additional diagnostics

  –, –ignore_rest
    Ignores the rest of the labeled arguments following this flag.

  –version
    Displays version information and exits.

  -h, –help
    Displays usage information and exits.

  IP_Address <string>
    (required) Target IP Address to probe.

  TCP_Port <positive integer.
    (required) Target TCP Port to probe.

  This is a telnet-style IP probe utility to test connectivity to a
specific IP address and port.

Examples

  1. The most common usage will be to query a specific address and port using the default options, e.g.:

> zuipp 10.27.186.207 21

Typical response:

IP Probe Utility Version: 1.0; built: Jun 7 2023 11:15:52
Creating TCP socket…
…Created socket 12582949
Setting receive/connect timeout of 10 seconds on socket 12582949…
…Options set, rc = 0
Connecting socket 12582949 to 10.27.186.207:21…
…Connected TCP socket, rc = 0
Sending on socket 12582949 (15 bytes): EtoA(Metatron speaks)…
…Sent 15 bytes
Receiving on socket 12582949…
…Received 42 bytes: 220 TPF FTP server (Version 1.02) ready.
Setting receive/connect timeout of 1 seconds on socket 12582949…
…Options set, rc = 0
Receiving on socket 12582949…
…Receive timeout: no data received
Closing TCP socket 12582949…
…Closed TCP socket, rc = 0
Test finished.

The response is a verbose explanation of all activities performed by the utility and their results.

  1. The data sent by the utility, the timeout for the initial connection and expected first receive, and the timeout for subsequent unexpected receives may be set by optional parameters.

For example, to override the text, wait 30 seconds for the connection and primary response, and 5 seconds for any additional responses:

> zuipp 10.27.186.207 21 –data “Messages with spaces may be sent using quotes” –timeout1 30 –timeout2 5

Errors

Some sort of error, usually on the first receive operation, is normal and expected, as the data sent by this utility will not be acceptable to most servers excepting the most primitive.

The reason for any error is clearly indicated in the applicable message. Numeric return codes are deciphered using z/tpf facilities, but this is, regrettably, incomplete. Thus, an indication is provided of which source segment the numeric value is likely to be enumerated in, in the hope that this might provide a clue to the failure, or at least a starting point for a search. (IBM is expected to issue a fix for this incompleteness later in 2023).

Source

SNCF z/TPF systems management have requested and authorised that this utility be made publically available. It has also been submitted to IBM should they wish to include it in the z/TPF distribution.

The complete source and full documentation for this utility may be obtained (here).

Programming notes

  • The following open-source projects are required for compilation:
  • I’m not a huge fan of the z/tpf iprse parser, preferring to use open-source options. For c++, cli11 is arguably the best of breed, and best documented, but this project uses tclap as sncf is currently using an older level of gcc incompatible with cli11.
  • The latest version of this utility has started to use the fmt project’s i/o classes to replace c stdio and c++ iostreams calls with modern c++20 std::format alternatives with much-improved capabilities. Not all previously existing code has been updated.
  • tclap requires a tokenised command line to be passed to it, which we would normally obtain from main()’s argv parameters, but z/tpf does not generate these from the command line, so instead we parse the input message ourselves, which means we can handle quoted strings with spaces in them, for example.
  • Sncf’s uenv.c does not correctly define the stdout and stderr environment variables so, at the very start of the program, we open the correct paths so that writes to stdoutm stderr, cout, and cerr work correctly. I am, obviously, unable to verify if the utility works with correctly-defined variables, but there is a #define which should turn this section of code off, if required.
  • The utility’s core routines are all gathered into a single class as a collection of static members, just for the sake of tidiness.

Thanks

This article is based on work performed for SNCF, and is published with their permission, for which many thanks.

Author

Ian S. Worthington has over 25 years’ experience as a developer and systems SME delivering solutions with high-volume, high-performance transaction processing systems using z/OS, z/TPF, ALCS, z/VM, and Linux on (and off) IBM Z. His customers have included IBM (three of ’em: US, UK, and India), British Airways, American Express, Citibank (Assoc Bancorp), and currently SNCF. He holds a BSc in Applied Physics, and an MSc in Database and Information Science, both from the University of London.

© 2023 Ian S. Worthington